package com.qigao.mall.channel.weichat;

import com.alibaba.fastjson.JSON;
import com.qigao.mall.channel.ChannelCore;
import com.qigao.mall.channel.config.ChannelConstant;
import com.qigao.mall.channel.dto.ChannelRefundRespDto;
import com.qigao.mall.commons.dto.MerChannelDto;
import com.qigao.mall.commons.enums.*;
import com.qigao.mall.commons.param.ChannelReqParam;
import com.qigao.mall.commons.param.ChannelRespParam;
import com.qigao.mall.commons.utils.DateUtil;
import com.qigao.mall.commons.utils.PayUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 文档链接：https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_20&index=1
 */
@Service
public class WeichatRefundQuery extends AbstractWeichatTrade implements ChannelCore {

    @Resource
    ChannelConstant channelConstant;

    private static final Logger logger= LoggerFactory.getLogger(WeichatRefundQuery.class);

    @Override
    public boolean isSupport(PayProductEnum payProductEnum, ChannelActionEnum channelActionEnum, ChannelInfoEnum channelInfoEnum) {
        return ChannelActionEnum.REFUND_QUERY.equals(channelActionEnum) && channelInfoEnum.equals(ChannelInfoEnum.WEICHAT);
    }

    @Override
    protected String getSelfReqUrl() {
        return channelConstant.getWeichatRefundQueryUrl();
    }

    @Override
    public Map buildSelfReqParam(MerChannelDto merChannelDto, ChannelReqParam channelReqParam) {
        Map reqParam=new ConcurrentHashMap<String,String>();
        reqParam.put("appid", merChannelDto.getAppId());
        reqParam.put("mch_id", merChannelDto.getChannelPartenerNo());
        reqParam.put("nonce_str", PayUtil.getRandomString(16));
        // reqParam.put("transaction_id", merChannelDto.getThirdSeqNo());
        reqParam.put("out_refund_no", merChannelDto.getInnerRefundSeqNo());
        return reqParam;
    }

    @Override
    protected ChannelRespParam buildSelfRespData(Map respMap, MerChannelDto merChannelDto) {
        ChannelRefundRespDto channelRefundRespDto = new ChannelRefundRespDto();
        channelRefundRespDto.setInnerSeqNo((String) respMap.get("out_trade_no"));
        channelRefundRespDto.setInnerRefundNo((String) respMap.get("out_refund_no_0"));
        String refundFee=(String) respMap.get("refund_fee");
        BigDecimal refundAmt=new BigDecimal(refundFee).divide(new BigDecimal(100));
        channelRefundRespDto.setRefundAmt(refundAmt);
        channelRefundRespDto.setThirdRefundNo((String) respMap.get("refund_id_0"));
        String transactionId=(String) respMap.get("transaction_id");
        channelRefundRespDto.setThirdTradeNo(transactionId);
        String resultCode=(String) respMap.get("result_code");
        channelRefundRespDto.setRetCode(resultCode);
        String returnMsg=(String) respMap.get("return_msg");
        channelRefundRespDto.setRetMsg(returnMsg);
        if("FAIL".equals(resultCode)){
            String errCode=(String) respMap.get("err_code");
            channelRefundRespDto.setRetCode(errCode);
            String errmsg=(String) respMap.get("err_code_des");
            channelRefundRespDto.setRetMsg(errmsg);
            if("REFUNDNOTEXIST".equals(errCode)){//退款不存在则关闭
                channelRefundRespDto.setRefundStatus(RefundStatusEnum.REFUND_CLOSE);
            }
        }else {
            /**
             * SUCCESS—退款成功
             *
             * REFUNDCLOSE—退款关闭。
             *
             * PROCESSING—退款处理中
             *
             * CHANGE—退款异常，退款到银行发现用户的卡作废或者冻结了，导致原路退款银行卡失败，可前往商户平台（pay.weixin.qq.com）-交易中心，手动处理此笔退款。$n为下标，从0开始编号。
             */
            if("SUCCESS".equals(respMap.get("refund_status_0"))){
                channelRefundRespDto.setRefundStatus(RefundStatusEnum.REFUND_SUCCESS);
            }else if("REFUNDCLOSE".equals(respMap.get("refund_status_0"))){
                channelRefundRespDto.setRefundStatus(RefundStatusEnum.REFUND_CLOSE);
            }else if("CHANGE".equals(respMap.get("refund_status_0"))) {
                channelRefundRespDto.setRefundStatus(RefundStatusEnum.REFUND_FAIL);
            }else if("PROCESSING".equals(respMap.get("refund_status_0"))) {
                channelRefundRespDto.setRefundStatus(RefundStatusEnum.REFUND_INIT);
            }
            channelRefundRespDto.setRefundSuccessDate(DateUtil.pareDate((String) respMap.get("refund_success_time_0"),"yyyy-MM-dd HH:mm:ss"));
        }
        String retStr= JSON.toJSONString(channelRefundRespDto);
        ChannelRespParam channelRespParam=new ChannelRespParam();
        channelRespParam.setRespCode(ChannelCodeEnum.SUCCESS.getCode());
        channelRespParam.setRespMsg(ChannelCodeEnum.SUCCESS.getName());
        channelRespParam.setRespContent(retStr);
        return  channelRespParam;
    }

}
